#include "ComponentManager.h"

#include "Visualisation.h"
#include "Audio.h"
#include "UserInterfaceWin.h"
#include "UserInterfaceGP2X.h"
#include "WorldModel.h"
#include "LoggerConsole.h"
#include "SceneManager.h"
#include "ProjectileManager.h"
#include "ExplosionManager.h"
#include "FileManager.h"


#ifdef _WIN
#include "LoggerDebug.h"
#include "LoggerMsgBox.h"
#include "ProfilerWin.h"
#endif

#ifdef _GP2X
#include "ProfilerGP2X.h"
#endif

#include <iostream>
using namespace std;

CComponentManager* CComponentManager::m_instance=0;

CComponentManager::CComponentManager():m_visualisationComponent(0), m_audioComponent(0), m_uiComponent(0),
m_worldModel(0), m_loggerConsole(0), m_loggerDebug(0), m_loggerMsgBox(0), m_sceneManager(0), m_projectileManager(0),
m_profiler(0), m_explosionManager(0){}

CComponentManager::~CComponentManager()
{
	if(m_visualisationComponent!=0)
		delete m_visualisationComponent;
	if(m_audioComponent!=0)
		delete m_audioComponent;
	if(m_uiComponent!=0)
		delete m_uiComponent;
	if(m_worldModel!=0)
		delete m_worldModel;
	if(m_sceneManager!=0)
		delete m_sceneManager;
	if(m_projectileManager != 0)
		delete m_projectileManager;
	if(m_profiler != 0)
		delete m_profiler;
	if(m_loggerConsole!=0)
		delete m_loggerConsole;
	if(m_explosionManager!=0)
		delete m_explosionManager;
	if(m_fileManager != 0)
		delete m_fileManager;

#ifdef _WIN
	if(m_loggerDebug!=0)
		delete m_loggerDebug;
	if(m_loggerMsgBox!=0)
		delete m_loggerMsgBox;
#endif

}

CComponentManager& CComponentManager::getInstance(void)
{
	if(m_instance==0)
		m_instance=new CComponentManager();

	return *m_instance;
}

void CComponentManager::close()
{
	delete m_instance;
	m_instance=0;
}

bool CComponentManager::initVisualisationComponent(const string& visualisationName)
{
	bool returnValue = false;
	if(visualisationName.compare("SDL_Visualisation") == 0)
	{
		m_visualisationComponent = new CVisualisation();
		returnValue = m_visualisationComponent->init();
	}

	if(returnValue)//if the initialisation went well
	{
		if(m_loggerConsole)//if the logger is initialised
			m_loggerConsole->Log()<<"LOG : CM : Visualisation component initialised\n";
		else //if the logger is not initialised
			cout<<"LOG : CM : Visualisation component initialised\n";
	}
	else //if the initialisation failed
	{
		if(m_loggerConsole)//if the logger is initialised
			m_loggerConsole->Log()<<"LOG : CM : ERROR : Cannot initialise the visualisation component\n";
		else//if the logger is not initialised
			cout<<"LOG : CM : ERROR : Cannot initialise the visualisation component\n";
	}
	return returnValue;
}

bool CComponentManager::initAudioComponent(const string& audioName)
{
	bool returnValue = false;
	if(audioName.compare("SDL_Audio")==0)
	{
		m_audioComponent = new CAudio();
		returnValue = m_audioComponent->init();
	}
	if(returnValue)//if the initialisation went well
	{
		if(m_loggerConsole)//if the logger is initialised
			m_loggerConsole->Log()<<"LOG : CM : Audio component initialised\n";
		else //if the logger is not initialised
			cout<<"LOG : CM : Audio component initialised\n";
	}
	else //if the initialisation failed
	{
		if(m_loggerConsole)//if the logger is initialised
			m_loggerConsole->Log()<<"LOG : CM : ERROR : Cannot initialise the audio component\n";
		else//if the logger is not initialised
			cout<<"LOG : CM : ERROR : Cannot initialise the audio component\n";
	}
	return returnValue;
}

bool CComponentManager::initUIComponent(const string& uiName)
{
	bool returnValue = false;
	if(uiName.compare("WINDOWS_UInterface")==0)
	{
		m_uiComponent = new CUserInterfaceWin();
		returnValue = m_uiComponent->init();
	}
	else if(uiName.compare("GP2X_UInterface")==0)
	{
		m_uiComponent = new CUserInterfaceGP2X();
		returnValue = m_uiComponent->init();
	}
	if(returnValue)//if the initialisation went well
	{
		if(m_loggerConsole)//if the logger is initialised
			m_loggerConsole->Log()<<"LOG : CM : "<<uiName<<" component initialised\n";
		else //if the logger is not initialised
			cout<<"LOG : CM : "<<uiName<<" component initialised\n";
	}
	else //if the initialisation failed
	{
		if(m_loggerConsole)//if the logger is initialised
			m_loggerConsole->Log()<<"LOG : CM : ERROR : Cannot initialise the UI component : "<<uiName<<"\n";
		else//if the logger is not initialised
			cout<<"LOG : ENGINE : CM : Cannot initialise the UI component: "<<uiName<<"\n";
	}
	return returnValue;
}

bool CComponentManager::initWorldModelComponent(const string& worldName)
{
	bool returnValue = false;
	if(worldName.compare("STANDARD_WorldModel")==0)
	{
		m_worldModel = new CWorldModel();
		returnValue = true;
	}

	if(returnValue)//if the initialisation went well
	{
		if(m_loggerConsole)//if the logger is initialised
			m_loggerConsole->Log()<<"LOG : CM : World component initialised\n";
		else //if the logger is not initialised
			cout<<"LOG : CM : World component initialised\n";
	}
	else //if the initialisation failed
	{
		if(m_loggerConsole)//if the logger is initialised
			m_loggerConsole->Log()<<"LOG : CM : ERROR : Cannot initialise the world component : "<<worldName<<"\n";
		else//if the logger is not initialised
			cout<<"LOG : CM : ERROR : Cannot initialise the world component: "<<worldName<<"\n";
	}
	return returnValue;
}

bool CComponentManager::initSceneManager(const string& sceneName)
{
	bool returnValue = false;
	if(sceneName.compare("STANDARD_SceneManager")==0)
	{
		m_sceneManager = new CSceneManager();
		returnValue = true;
	}

	if(returnValue)//if the initialisation went well
	{
		if(m_loggerConsole)//if the logger is initialised
			m_loggerConsole->Log()<<"LOG : CM : Scene manager component initialised\n";
		else //if the logger is not initialised
			cout<<"LOG : CM : Scene manager component initialised\n";
	}
	else //if the initialisation failed
	{
		if(m_loggerConsole)//if the logger is initialised
			m_loggerConsole->Log()<<"LOG : CM : ERROR : Cannot initialise the Scene manager component : "<<sceneName<<"\n";
		else//if the logger is not initialised
			cout<<"LOG : CM : ERROR : Cannot initialise the Scene manager component: "<<sceneName<<"\n";
	}
	return returnValue;
}

bool CComponentManager::initProjectileManager(const string& managerName)
{

	bool returnValue = false;
	if(managerName.compare("STANDARD_ProjectileManager")==0)
	{
		m_projectileManager = new CProjectileManager();
		returnValue = true;
	}

	if(returnValue)//if the initialisation went well
	{
		if(m_loggerConsole)//if the logger is initialised
			m_loggerConsole->Log()<<"LOG : CM : Projectile manager component initialised\n";
		else //if the logger is not initialised
			cout<<"LOG : CM : Projectile manager component initialised\n";
	}
	else //if the initialisation failed
	{
		if(m_loggerConsole)//if the logger is initialised
			m_loggerConsole->Log()<<"LOG : CM : ERROR : Cannot initialise the Projectile manager component : "<<managerName<<"\n";
		else//if the logger is not initialised
			cout<<"LOG : CM : ERROR : Cannot initialise the Projectile manager component: "<<managerName<<"\n";
	}
	return returnValue;
}

bool CComponentManager::initProfiler(const string& profilerName)
{
	bool returnValue = false;
#ifdef _WIN
	if(profilerName.compare("Profiler_WIN")==0)
	{
		m_profiler = new CProfilerWin();
		returnValue = true;
	}
#endif
#ifdef _GP2X
	if(profilerName.compare("Profiler_GP2X")==0)
	{
		m_profiler = new CProfilerGP2X();
		returnValue = true;
	}
#endif

	if(returnValue)//if the initialisation went well
	{
		if(m_loggerConsole)//if the logger is initialised
			m_loggerConsole->Log()<<"LOG : CM : Profiler component initialised\n";
		else //if the logger is not initialised
			cout<<"LOG : CM : Profiler component initialised\n";
	}
	else //if the initialisation failed
	{
		if(m_loggerConsole)//if the logger is initialised
			m_loggerConsole->Log()<<"LOG : CM : ERROR : Cannot initialise the Profiler component : "<<profilerName<<"\n";
		else//if the logger is not initialised
			cout<<"LOG : CM : ERROR : Cannot initialise the Profiler component: "<<profilerName<<"\n";
	}
	return returnValue;
}

bool CComponentManager::initLogger(const string& loggerName)
{
	bool returnValue = false;
	if(loggerName.compare("LOG_Console")==0)
	{
		m_loggerConsole = new CLoggerConsole();
		returnValue = true;
	}
#ifdef _WIN
	else if(loggerName.compare("LOG_Debug")==0)
	{
		m_loggerDebug = new CLoggerDebug();
		returnValue = true;
	}
	else if (loggerName.compare("LOG_MsgBox")==0)
	{
		m_loggerMsgBox = new CLoggerMsgBox();
		returnValue = true;
	}
#endif

	if(returnValue)//if the initialisation went well
	{
		if(m_loggerConsole)//if the logger is initialised
			m_loggerConsole->Log()<<"LOG : CM : log initialised : "<<loggerName<<"\n";
		else //if the logger is not initialised
			cout<<"LOG : CM : log initialised : "<<loggerName<<"\n";
	}
	else //if the initialisation failed
	{
		if(m_loggerConsole)//if the logger is initialised
			m_loggerConsole->Log()<<"LOG : CM : ERROR : Cannot initialise the log component : "<<loggerName<<"\n";
		else//if the logger is not initialised
			cout<<"LOG : CM : ERROR : Cannot initialise the log component : "<<loggerName<<"\n";
	}
	return returnValue;
}

bool CComponentManager::initExplosionManager(const string& managerName)
{
	bool returnValue = false;
	if(managerName.compare("STANDARD_ExplosionManager")==0)
	{
		m_explosionManager = new CExplosionManager();
		returnValue = true;
	}

	if(returnValue)//if the initialisation went well
	{
		if(m_loggerConsole)//if the logger is initialised
			m_loggerConsole->Log()<<"LOG : CM : Explosion manager component initialised\n";
		else //if the logger is not initialised
			cout<<"LOG : CM : Explosion manager component initialised\n";
	}
	else //if the initialisation failed
	{
		if(m_loggerConsole)//if the logger is initialised
			m_loggerConsole->Log()<<"LOG : CM : ERROR : Cannot initialise the Explosion manager component : "<<managerName<<"\n";
		else//if the logger is not initialised
			cout<<"LOG : CM : ERROR : Cannot initialise the Explosion manager component: "<<managerName<<"\n";
	}
	return returnValue;
}

bool CComponentManager::initFileManager(const string& managerName)
{
	bool returnValue = false;
	if(managerName.compare("STANDARD_FileManager")==0)
	{
		m_fileManager = new CFileManager();
		returnValue = true;
	}

	if(returnValue)//if the initialisation went well
	{
		if(m_loggerConsole)//if the logger is initialised
			m_loggerConsole->Log()<<"LOG : CM : File manager component initialised\n";
		else //if the logger is not initialised
			cout<<"LOG : CM : File manager component initialised\n";
	}
	else //if the initialisation failed
	{
		if(m_loggerConsole)//if the logger is initialised
			m_loggerConsole->Log()<<"LOG : CM : ERROR : Cannot initialise the File manager component : "<<managerName<<"\n";
		else//if the logger is not initialised
			cout<<"LOG : CM : ERROR : Cannot initialise the File manager component: "<<managerName<<"\n";
	}
	return returnValue;
}

IVisualisation& CComponentManager::VISU(void)
{
	return *m_visualisationComponent;
}

IAudio& CComponentManager::AUDIO(void)
{
	return *m_audioComponent;
}

IUserInterface& CComponentManager::UI(void)
{
	return *m_uiComponent;
}

IWorldModel& CComponentManager::WORLD(void)
{
	return *m_worldModel;
}

ILogger& CComponentManager::LOGCONSOLE(void)
{
	return *m_loggerConsole;
}

ISceneManager& CComponentManager::SCENE(void)
{
	return *m_sceneManager;
}

IProjectileManager& CComponentManager::PROJECTILE(void)
{
	return *m_projectileManager;
}

IProfiler& CComponentManager::PROFILER(void)
{
	return *m_profiler;
}

IExplosionManager& CComponentManager::EXPLOSION(void)
{
	return *m_explosionManager;
}

IFileManager& CComponentManager::FILE(void)
{
	return *m_fileManager;
}

#ifdef _WIN
ILogger& CComponentManager::LOGDEBUG(void)
{
	return *m_loggerDebug;
}

ILogger& CComponentManager::LOGMSGBOX(void)
{
	return *m_loggerMsgBox;
}
#endif

